package com.supreme.commonrocketmq.aspect;

import com.supreme.common.entityRocketmq.MQLogger;
import com.supreme.commonboot.utils.AspectUtils;
import com.supreme.commonrocketmq.annotation.LoggerRecord;
import com.supreme.commonrocketmq.config.props.RocketmqProps;
import com.supreme.commonrocketmq.utils.RocketmqSendUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.AnnotationUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Objects;

@Slf4j
@Aspect
//@Component
public class LoggerAspect {

    @Resource
    private HttpServletRequest httpServletRequest;

    @Resource
    private RocketmqProps rocketmqProps;

    @Resource
    private DefaultMQProducer loggerProducer;

    /**
     * @within(com.supreme.commonrocketmq.annotation.LoggerRecord)
     * @annotation(com.supreme.commonrocketmq.annotation.LoggerRecord)
     */
    @Pointcut(value = "@within(com.supreme.commonrocketmq.annotation.LoggerRecord) || @annotation(com.supreme.commonrocketmq.annotation.LoggerRecord)")
    public void PointCut() {
    }

    @After("PointCut()")
    public void afterMethod(JoinPoint joinPoint) {
        boolean printInfo = false;
        boolean loggerMqSend = false;
        String loggerMqType = LoggerRecord.MQ_ROCKETMQ;

        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        LoggerRecord loggerRecordAnno = AnnotationUtils.findAnnotation(method, LoggerRecord.class);
        if (Objects.nonNull(loggerRecordAnno)) {
            printInfo = loggerRecordAnno.printInfo();
            loggerMqSend = loggerRecordAnno.mqSend();
            loggerMqType = loggerRecordAnno.mqType();
        } else {
            Class<?> declaringType = methodSignature.getDeclaringType();
            loggerRecordAnno = AnnotationUtils.findAnnotation(declaringType, LoggerRecord.class);
            if (Objects.nonNull(loggerRecordAnno)) {
                printInfo = loggerRecordAnno.printInfo();
                loggerMqSend = loggerRecordAnno.mqSend();
                loggerMqType = loggerRecordAnno.mqType();
            }
        }

        if (printInfo) {
            AspectUtils.printJoinPointInfo(joinPoint);
            AspectUtils.printServletRequestInfo();
        }

        if (loggerMqSend) {
            switch (loggerMqType) {
                case LoggerRecord.MQ_ROCKETMQ:
                    MQLogger loggerPayload = RocketmqSendUtils.buildLoggerPayload(joinPoint, httpServletRequest);
                    String loggerTopic = rocketmqProps.getLogger().getName();
                    RocketmqSendUtils.sendMessage(loggerProducer, loggerTopic, loggerPayload);
                    break;

                case LoggerRecord.MQ_KAFKA:
                    break;
            }
        }
    }
}
